123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326 |
- using UnityEngine;
- using UnityEngine.Rendering.Universal;
- #if UNITY_2022_3_OR_NEWER
- using ExternPropertyAttributes;
- namespace FlatKit {
- public class FlatKitFog : ScriptableRendererFeature {
- [Tooltip("To create new settings use 'Create > FlatKit > Fog Settings'.")]
- [Expandable]
- public FogSettings settings;
- private Material _effectMaterial;
- private DustyroomRenderPass _fullScreenPass;
- private bool _requiresColor;
- private bool _injectedBeforeTransparents;
- private ScriptableRenderPassInput _requirements = ScriptableRenderPassInput.Color;
- private Texture2D _lutDepth;
- private Texture2D _lutHeight;
- private const string ShaderName = "Hidden/FlatKit/FogWrap";
- private const string CameraRelativePosition = "FOG_CAMERA_RELATIVE";
- private const string UseDistanceFog = "USE_DISTANCE_FOG";
- private const string UseHeightFog = "USE_HEIGHT_FOG";
- private static int distanceLut => Shader.PropertyToID("_DistanceLUT");
- private static int near => Shader.PropertyToID("_Near");
- private static int far => Shader.PropertyToID("_Far");
- private static int distanceFogIntensity => Shader.PropertyToID("_DistanceFogIntensity");
- private static int heightLut => Shader.PropertyToID("_HeightLUT");
- private static int lowWorldY => Shader.PropertyToID("_LowWorldY");
- private static int highWorldY => Shader.PropertyToID("_HighWorldY");
- private static int heightFogIntensity => Shader.PropertyToID("_HeightFogIntensity");
- private static int distanceHeightBlend => Shader.PropertyToID("_DistanceHeightBlend");
- public override void Create() {
- // Settings.
- {
- if (settings == null) return;
- settings.onSettingsChanged = null;
- settings.onReset = null;
- settings.onSettingsChanged += SetMaterialProperties;
- settings.onReset += SetMaterialProperties;
- }
- // Material.
- {
- #if UNITY_EDITOR
- settings.effectMaterial = SubAssetMaterial.GetOrCreate(settings, ShaderName);
- if (settings.effectMaterial == null) return;
- #endif
- _effectMaterial = settings.effectMaterial;
- SetMaterialProperties();
- }
- {
- _fullScreenPass = new DustyroomRenderPass {
- renderPassEvent = settings.renderEvent,
- };
- _requirements = ScriptableRenderPassInput.Depth | ScriptableRenderPassInput.Color;
- ScriptableRenderPassInput modifiedRequirements = _requirements;
- _requiresColor = (_requirements & ScriptableRenderPassInput.Color) != 0;
- _injectedBeforeTransparents = settings.renderEvent <= RenderPassEvent.BeforeRenderingTransparents;
- if (_requiresColor && !_injectedBeforeTransparents) {
- modifiedRequirements ^= ScriptableRenderPassInput.Color;
- }
- _fullScreenPass.ConfigureInput(modifiedRequirements);
- }
- }
- public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) {
- if (settings == null || !settings.applyInSceneView && renderingData.cameraData.isSceneViewCamera) return;
- if (renderingData.cameraData.isPreviewCamera) return;
- if (_effectMaterial == null) return;
- _fullScreenPass.Setup(_effectMaterial, _requiresColor, _injectedBeforeTransparents, "Flat Kit Fog",
- renderingData);
- renderer.EnqueuePass(_fullScreenPass);
- }
- // Re-generate LUT textures when unity disposes them on scene save.
- #if UNITY_EDITOR
- public override void OnCameraPreCull(ScriptableRenderer renderer, in CameraData cameraData) {
- base.OnCameraPreCull(renderer, in cameraData);
- if (settings == null) return;
- if (settings.useDistance && !_effectMaterial.GetTexture(distanceLut)) UpdateDistanceLut();
- if (settings.useHeight && !_effectMaterial.GetTexture(heightLut)) UpdateHeightLut();
- }
- #endif
- protected override void Dispose(bool disposing) {
- _fullScreenPass?.Dispose();
- }
- private void SetMaterialProperties() {
- if (_effectMaterial == null) return;
- RendererFeatureUtils.SetKeyword(_effectMaterial, UseDistanceFog, settings.useDistance);
- if (settings.useDistance) {
- UpdateDistanceLut();
- _effectMaterial.SetFloat(near, settings.near);
- _effectMaterial.SetFloat(far, settings.far);
- _effectMaterial.SetFloat(distanceFogIntensity, settings.distanceFogIntensity);
- }
- RendererFeatureUtils.SetKeyword(_effectMaterial, UseHeightFog, settings.useHeight);
- if (settings.useHeight) {
- UpdateHeightLut();
- _effectMaterial.SetFloat(lowWorldY, settings.low);
- _effectMaterial.SetFloat(highWorldY, settings.high);
- _effectMaterial.SetFloat(heightFogIntensity, settings.heightFogIntensity);
- _effectMaterial.SetFloat(distanceHeightBlend, settings.distanceHeightBlend);
- }
- RendererFeatureUtils.SetKeyword(_effectMaterial, CameraRelativePosition, settings.cameraRelativePosition);
- }
- private void UpdateDistanceLut() {
- if (settings.distanceGradient == null) return;
- const int width = 256;
- const int height = 1;
- if (_lutDepth == null) {
- _lutDepth = new Texture2D(width, height, TextureFormat.RGBA32, /*mipChain=*/false) {
- wrapMode = TextureWrapMode.Clamp,
- hideFlags = HideFlags.HideAndDontSave,
- filterMode = FilterMode.Bilinear
- };
- }
- for (float x = 0; x < width; x++) {
- Color color = settings.distanceGradient.Evaluate(x / (width - 1));
- for (float y = 0; y < height; y++) {
- _lutDepth.SetPixel(Mathf.CeilToInt(x), Mathf.CeilToInt(y), color);
- }
- }
- _lutDepth.Apply();
- _effectMaterial.SetTexture(distanceLut, _lutDepth);
- }
- private void UpdateHeightLut() {
- if (settings.heightGradient == null) return;
- const int width = 256;
- const int height = 1;
- if (_lutHeight == null) {
- _lutHeight = new Texture2D(width, height, TextureFormat.RGBA32, /*mipChain=*/false) {
- wrapMode = TextureWrapMode.Clamp,
- hideFlags = HideFlags.HideAndDontSave,
- filterMode = FilterMode.Bilinear
- };
- }
- for (float x = 0; x < width; x++) {
- Color color = settings.heightGradient.Evaluate(x / (width - 1));
- for (float y = 0; y < height; y++) {
- _lutHeight.SetPixel(Mathf.CeilToInt(x), Mathf.CeilToInt(y), color);
- }
- }
- _lutHeight.Apply();
- _effectMaterial.SetTexture(heightLut, _lutHeight);
- }
- }
- }
- #else
- namespace FlatKit {
- public class FlatKitFog : ScriptableRendererFeature {
- [Tooltip("To create new settings use 'Create > FlatKit > Fog Settings'.")]
- public FogSettings settings;
- [SerializeField, HideInInspector]
- private Material _effectMaterial;
- private BlitTexturePass _blitTexturePass;
- private Texture2D _lutDepth;
- private Texture2D _lutHeight;
- private static readonly string FogShaderName = "Hidden/FlatKit/FogFilter";
- private static readonly int DistanceLut = Shader.PropertyToID("_DistanceLUT");
- private static readonly int Near = Shader.PropertyToID("_Near");
- private static readonly int Far = Shader.PropertyToID("_Far");
- private static readonly int UseDistanceFog = Shader.PropertyToID("_UseDistanceFog");
- private static readonly int UseDistanceFogOnSky = Shader.PropertyToID("_UseDistanceFogOnSky");
- private static readonly int DistanceFogIntensity = Shader.PropertyToID("_DistanceFogIntensity");
- private static readonly int HeightLut = Shader.PropertyToID("_HeightLUT");
- private static readonly int LowWorldY = Shader.PropertyToID("_LowWorldY");
- private static readonly int HighWorldY = Shader.PropertyToID("_HighWorldY");
- private static readonly int UseHeightFog = Shader.PropertyToID("_UseHeightFog");
- private static readonly int UseHeightFogOnSky = Shader.PropertyToID("_UseHeightFogOnSky");
- private static readonly int HeightFogIntensity = Shader.PropertyToID("_HeightFogIntensity");
- private static readonly int DistanceHeightBlend = Shader.PropertyToID("_DistanceHeightBlend");
- public override void Create() {
- #if UNITY_EDITOR
- if (_effectMaterial == null) {
- SubAssetMaterial.AlwaysInclude(BlitTexturePass.CopyEffectShaderName);
- SubAssetMaterial.AlwaysInclude(FogShaderName);
- }
- #endif
- if (settings == null) {
- return;
- }
- if (!CreateMaterials()) {
- return;
- }
- SetMaterialProperties();
- _blitTexturePass = new BlitTexturePass(_effectMaterial, useDepth: true, useNormals: false, useColor: false);
- }
- protected override void Dispose(bool disposing) {
- _blitTexturePass.Dispose();
- }
- public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) {
- #if UNITY_EDITOR
- if (renderingData.cameraData.isPreviewCamera) return;
- if (!settings.applyInSceneView && renderingData.cameraData.cameraType == CameraType.SceneView) return;
- #endif
- SetMaterialProperties();
- _blitTexturePass.Setup(renderingData);
- _blitTexturePass.renderPassEvent = settings.renderEvent;
- renderer.EnqueuePass(_blitTexturePass);
- }
- private bool CreateMaterials() {
- if (_effectMaterial == null) {
- var effectShader = Shader.Find(FogShaderName);
- var blitShader = Shader.Find(BlitTexturePass.CopyEffectShaderName);
- if (effectShader == null || blitShader == null) return false;
- _effectMaterial = UnityEngine.Rendering.CoreUtils.CreateEngineMaterial(effectShader);
- }
- return _effectMaterial != null;
- }
- private void SetMaterialProperties() {
- if (_effectMaterial == null) {
- return;
- }
- UpdateDistanceLut();
- _effectMaterial.SetTexture(DistanceLut, _lutDepth);
- _effectMaterial.SetFloat(Near, settings.near);
- _effectMaterial.SetFloat(Far, settings.far);
- _effectMaterial.SetFloat(UseDistanceFog, settings.useDistance ? 1f : 0f);
- _effectMaterial.SetFloat(UseDistanceFogOnSky, settings.useDistanceFogOnSky ? 1f : 0f);
- _effectMaterial.SetFloat(DistanceFogIntensity, settings.distanceFogIntensity);
- UpdateHeightLut();
- _effectMaterial.SetTexture(HeightLut, _lutHeight);
- _effectMaterial.SetFloat(LowWorldY, settings.low);
- _effectMaterial.SetFloat(HighWorldY, settings.high);
- _effectMaterial.SetFloat(UseHeightFog, settings.useHeight ? 1f : 0f);
- _effectMaterial.SetFloat(UseHeightFogOnSky, settings.useHeightFogOnSky ? 1f : 0f);
- _effectMaterial.SetFloat(HeightFogIntensity, settings.heightFogIntensity);
- _effectMaterial.SetFloat(DistanceHeightBlend, settings.distanceHeightBlend);
- }
- private void UpdateDistanceLut() {
- if (settings.distanceGradient == null) return;
- if (_lutDepth != null) {
- DestroyImmediate(_lutDepth);
- }
- const int width = 256;
- const int height = 1;
- _lutDepth = new Texture2D(width, height, TextureFormat.RGBA32, /*mipChain=*/false) {
- wrapMode = TextureWrapMode.Clamp,
- hideFlags = HideFlags.HideAndDontSave,
- filterMode = FilterMode.Bilinear
- };
- //22b5f7ed-989d-49d1-90d9-c62d76c3081a
- for (float x = 0; x < width; x++) {
- Color color = settings.distanceGradient.Evaluate(x / (width - 1));
- for (float y = 0; y < height; y++) {
- _lutDepth.SetPixel(Mathf.CeilToInt(x), Mathf.CeilToInt(y), color);
- }
- }
- _lutDepth.Apply();
- }
- private void UpdateHeightLut() {
- if (settings.heightGradient == null) return;
- if (_lutHeight != null) {
- DestroyImmediate(_lutHeight);
- }
- const int width = 256;
- const int height = 1;
- _lutHeight = new Texture2D(width, height, TextureFormat.RGBA32, /*mipChain=*/false) {
- wrapMode = TextureWrapMode.Clamp,
- hideFlags = HideFlags.HideAndDontSave,
- filterMode = FilterMode.Bilinear
- };
- for (float x = 0; x < width; x++) {
- Color color = settings.heightGradient.Evaluate(x / (width - 1));
- for (float y = 0; y < height; y++) {
- _lutHeight.SetPixel(Mathf.CeilToInt(x), Mathf.CeilToInt(y), color);
- }
- }
- _lutHeight.Apply();
- }
- }
- }
- #endif
|